home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / genial / func / poly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-14  |  4.5 KB  |  205 lines

  1. /*
  2.  * poly.c -- routines for drawing polygons
  3.  *
  4.  */
  5.  
  6. #include "reg.h"
  7. #include "common.h"
  8. #include "llist.h"
  9. #include "display.h"
  10. #include "ui.h"
  11. #include <X11/Xlib.h>
  12. #include <stdio.h>
  13.  
  14. draw_polygon(reg)
  15.     struct region *reg;
  16. {
  17.     poly_interp(reg->r_dlist, reg->r_plist);
  18.     draw_dlist(img_win->d_xid, reg->r_dlist);
  19. }
  20.  
  21. poly_interp(dlist, ptlist)
  22.     struct dlist *dlist;
  23.     struct plist *ptlist;
  24. {
  25.     struct plist *org, *dst;
  26.     struct dlist *seg;
  27.  
  28.     seg = dlist;
  29.     for (org = ptlist, dst = org->next; dst != NULL; org = dst, dst = org->next) {
  30.     ras_line(org->pt, dst->pt, seg, orig_ximg, orig_img);
  31.     seg = (struct dlist *) malloc(sizeof(struct dlist));
  32.     llist_add((llist *) seg, (llist **) & dlist, (llist **) NULL);
  33.     }
  34.     ras_line(org->pt, ptlist->pt, seg, orig_ximg, orig_img);
  35. }
  36.  
  37. /*****************************************************************/
  38.  
  39. char     *
  40. polygon_info(reg)        /* create string containing message giving
  41.                  * info on spline */
  42.     struct region *reg;
  43. {
  44.     char      mesg[80];
  45.     int       xmax, xmin, ymax, ymin, width, height, area;
  46.     struct plist *tr;
  47.  
  48.     xmax = xmin = reg->r_plist->pt.x;
  49.     ymax = ymin = reg->r_plist->pt.y;
  50.  
  51.     /* find min and max of points defining the spline */
  52.  
  53.     for (tr = reg->r_plist; tr != NULL; tr = tr->next) {
  54.     if (tr->pt.x > xmax)
  55.         xmax = tr->pt.x;
  56.     if (tr->pt.x < xmin)
  57.         xmin = tr->pt.x;
  58.     if (tr->pt.y > ymax)
  59.         ymax = tr->pt.y;
  60.     if (tr->pt.y < ymin)
  61.         ymin = tr->pt.y;
  62.     }
  63.     width = xmax - xmin;
  64.     height = ymax - ymin;
  65.     area = convex_poly_area(reg->r_plist);
  66.  
  67.     sprintf(mesg, "Polygon width: %d pixels;  height: %d pixels;  area: %d ",
  68.         width, height, area);
  69.  
  70.     return (mesg);
  71. }
  72.  
  73. /**************************************************************/
  74. int
  75. convex_poly_area(verts)
  76.     struct plist *verts;
  77. {
  78.     typedef struct PointStruct {
  79.     int    x, y;
  80.     }         Point;
  81.  
  82.     /* This routine is adapted from the method used in Graphics Gems,
  83.      but simplifed for the 2D case. I dont completely understand the
  84.      math here, so I hope this gives the correct results.... -BT
  85.      */
  86.  
  87.     float     area_sum = 0., area;
  88.     Point    p0, p1, p2;
  89.     struct plist *pinfo;
  90.  
  91.     /* compute areas of the sub-triangles of a polygon */
  92.  
  93.     pinfo = verts;
  94.     p0.x = pinfo->pt.x;
  95.     p0.y = pinfo->pt.y;
  96.     pinfo = pinfo->next;
  97.     p1.x = pinfo->pt.x;
  98.     p1.y = pinfo->pt.y;
  99.     while (pinfo->next != NULL) {
  100.     pinfo = pinfo->next;
  101.         p2.x = pinfo->pt.x;
  102.         p2.y = pinfo->pt.y;
  103.  
  104.     area = (.5 * (float)abs(((p1.x - p0.x) * (p2.y - p0.y)) - 
  105.              ((p1.y - p0.y) * (p2.x - p0.x))));
  106.  
  107.         area_sum += area;
  108.  
  109.     p1.x = p2.x;
  110.     p1.y = p2.y;
  111.     }
  112.     return ((int) (area_sum + .5));
  113. }
  114.  
  115. /**************************************************************/
  116.  
  117. #ifdef OLD_METHOD
  118. /* adapted from "Graphics Gems", Academic Press, 1990
  119.  *
  120.  * original routines were for 3D polygons, so as a quick hack
  121.  * I just set the z-component equal to 1. There is most certainly
  122.  * a 2D version that would be faster
  123.  */
  124.  
  125. typedef struct PointStruct {
  126.     double    x, y, z;
  127. }         Point3;
  128. typedef Point3 Vector3;
  129.  
  130. int
  131. convex_poly_area(verts)
  132.     struct plist *verts;
  133. {
  134.     int       i;
  135.     float     area_sum = 0;
  136.     Vector3   v1, v2, v3, *V3Cross(), *V3Sub();
  137.     Point3    p0, p1, p2;
  138.     double    V3Length();
  139.     struct plist *pinfo;
  140.  
  141.     /* compute relative areas of the sub-triangles of polygon */
  142.  
  143.     pinfo = verts;
  144.     p0.x = pinfo->pt.x;
  145.     p0.y = pinfo->pt.y;
  146.     p0.z = p1.z = p2.z = 1.;
  147.     pinfo = pinfo->next;
  148.     p1.x = pinfo->pt.x;
  149.     p1.y = pinfo->pt.y;
  150.     while (pinfo->next != NULL) {
  151.     pinfo = pinfo->next;
  152.         p2.x = pinfo->pt.x;
  153.         p2.y = pinfo->pt.y;
  154.     V3Sub(&p1, &p0, &v1);
  155.     V3Sub(&p2, &p0, &v2);
  156.     v1.z = v2.z = v3.z = 1.0;
  157.     V3Cross(&v1, &v2, &v3);
  158.     area_sum += (.5 * V3Length(&v3));
  159.  
  160.     p1.x = p2.x;
  161.     p1.y = p2.y;
  162.     }
  163.     return ((int) (area_sum + .5));
  164. }
  165.  
  166. /* return the cross product c = a cross b */
  167. Vector3  *
  168. V3Cross(a, b, c)
  169.     Vector3  *a, *b, *c;
  170. {
  171.     c->x = (a->y * b->z) - (a->z * b->y);
  172.     c->y = (a->z * b->x) - (a->x * b->z);
  173.     c->z = (a->x * b->y) - (a->y * b->x);
  174.     return (c);
  175. };
  176.  
  177. /* return vector difference c = a-b */
  178. Vector3  *
  179. V3Sub(a, b, c)
  180.     Vector3  *a, *b, *c;
  181. {
  182.     c->x = a->x - b->x;
  183.     c->y = a->y - b->y;
  184.     c->z = a->z - b->z;
  185.     return (c);
  186. };
  187.  
  188. /* returns squared length of input vector */
  189. double
  190. V3SquaredLength(a)
  191.     Vector3  *a;
  192. {
  193.     return ((a->x * a->x) + (a->y * a->y) + (a->z * a->z));
  194. };
  195.  
  196. /* returns length of input vector */
  197. double
  198. V3Length(a)
  199.     Vector3  *a;
  200. {
  201.     return (sqrt(V3SquaredLength(a)));
  202. };
  203.  
  204. #endif
  205.